package dao.dao.impl;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import dao.dao.Dao;
import dao.dao.DaoException;
import dao.dao.PreSQL;
import dao.dao.RowMapper;
public class DaoImp implements Dao {
	//属性一般情况下用private访问修饰符修饰
	private static String driver="oracle.jdbc.OracleDriver";
	private static String url="jdbc:oracle:thin:@localhost:1521:ORCL";
	private static String user="scott";
	private static String password="tiger"; 
	private Connection con;
	private List<PreparedStatement> pts=new ArrayList<PreparedStatement>(); 
	private PreparedStatement pt;
	private List<ResultSet> rss=new ArrayList<ResultSet>(); 
	private ResultSet rs;
	private static final Logger logger =(Logger) LogManager.getLogger(DaoImp.class.getName());
	private boolean flag=false;
	//仅需要加载一次驱动，所以通过静态块加载驱动
	static {
		try {
			Class.forName(driver);
			logger.debug("加载驱动成功！");
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
			throw new DaoException("加载驱动失败",e);	
		}
	}
	public DaoImp() {//通过无参构造建立连接
		try {
			con=DriverManager.getConnection(url, user, password);
			logger.debug("获取连接成功！");
			con.setAutoCommit(false);//设置事务：不自动提交
		} catch (SQLException e) {
			e.printStackTrace();
			throw new DaoException("驱动管理器与数据库连接失败",e);	
		}
	}
	//createPreparedStatement:获取pt
	private PreparedStatement createPreparedStatement(String sql) throws SQLException {
		logger.debug("Sql语句："+sql);
		pt=con.prepareStatement(sql);
		pts.add(pt);
		return pt;	
	}
	//setArgs(PreparedStatement pt,Object... args):设置数组参数
	private PreparedStatement setArgs(PreparedStatement pt,Object... args) throws SQLException {
		//StringBuilder str=new StringBuilder();
		for(int i=0,j=1;i<args.length;i++,j++) {
			if (args[i] instanceof java.util.Date) {
				Timestamp date=new java.sql.Timestamp(((Date) args[i]).getTime());
				pt.setObject(i+1, date);
			} else {
				pt.setObject(j, args[i]);
			}
			/*
			if(args[i].getClass()==java.util.Date.class){
				Timestamp date=new java.sql.Timestamp(((Date) args[i]).getTime());
				pt.setObject(i+1, date);
			}else{
				pt.setObject(i+1, args[i]);
			}
			
			//logger.debug("参数"+args[i]);
			str.append(args[i]);
			str.append(" ");
			*/
		}
		return pt;
	}
	/**
	 * getResultSet():获取结果集
	 * @param pt
	 * @return
	 * @throws SQLException
	 */
	private ResultSet getResultSet(PreparedStatement pt)throws SQLException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		rs=pt.executeQuery();
		rss.add(rs);
		return rs;		
	}
	/**
	 * 执行查询sql，返回ResultSet
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */ 
	public ResultSet query(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		try {
			pt=createPreparedStatement(sql);
			setArgs(pt,args);
			rs=getResultSet(pt);
			return rs;
		} catch (SQLException e) {
			e.printStackTrace();
			throw new DaoException("数据库查询失败", e);
		}
	}
	/**
	 * 执行更新sql，返回影响行数
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public int update(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		for (int i = 0; i < args.length; i++) {
			logger.debug(args[i]);
		}
		logger.debug("Sql语句："+sql);
		try {
			return setArgs(createPreparedStatement(sql), args).executeUpdate();
		}catch(SQLException e) {
			e.printStackTrace();
			throw new DaoException("获取行数失败", e);
		}
	}
	@Override //关闭资源
	public void close() {
		// 关闭结果集
		Iterator<ResultSet> rest = rss.iterator();
		while (rest.hasNext()) {
			ResultSet obj = rest.next();
			try {
				obj.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		rss.clear();
		// 关闭预编译sql语句
		Iterator<PreparedStatement> it = pts.iterator();
		while (it.hasNext()) {
			PreparedStatement ob = it.next();
			try {
				ob.close();
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
		pts.clear();
		// 关闭数据库连接
				try {
					con.close();
				} catch (Exception e) {
					e.printStackTrace();
				}
				con = null;
		/*
			try {
				for(ResultSet rs:rss){
					if(rs!=null) {
						rs.close();
					}
				}
				for(PreparedStatement pt:pts){
					if(pt!=null) {
						pt.close();
					}
				}
				if(con!=null) {
					con.close();
				}
				logger.debug("关闭资源");
			} catch (SQLException e) {
				e.printStackTrace();
			}
			*/
	}
	/**
	 * 执行select语句，返回被封装为List集合的查询结果，集合中的每一个元素为一个Java对象封装一行数据。
	 * 注：如何将一行数据封装为Java对象由RowMapper类型的对象参数决定。
	 * @param mapper
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public  <T> List<T> queryList(RowMapper<T> mapper, String sql, Object... args) throws DaoException {
		// RowMapper :可以将数据中的每一行数据封装成用户定义的类.
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		List <T> list=new ArrayList<>();
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			while(rs.next()) {
				try {
					list.add(mapper.toObject(rs));
				}catch(Exception e) {
					throw new DaoException("封装集合查询失败", e);
				}
			}
			return list;
		}catch(SQLException e) {
			throw new DaoException(e);
		}
	}
	/**
	 * 执行select语句，返回被封装为Java对象的第一行查询结果。
	 * 注：如何将一行数据封装为Java对象由RowMapper类型的对象参数决定。
	 * @param mapper
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public <T> T queryUnique(RowMapper<T> mapper, String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			if(rs.next()){
				return mapper.toObject(rs);
			}
			return null;
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("封装第一行查询结果失败", e);
		}
	}
	/**
	 * 执行select语句，返回被封装为String对象的第一行的第一列数据。
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public String queryString(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			while(rs.next()){
				return rs.getString(1);//光标所在行对应列的值
			}
			return null;
		}catch(Exception e) {
			throw new DaoException("获取String对象第一行第一列失败", e);
		}		
	}
	/**
	 * 执行select语句，返回被封装为List集合第一列数据，集合中的每一个元素为一个String对象封装一行的第一列数据。
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public List<String> queryStringList(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		List<String> list=new ArrayList<>();
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			while(rs.next()) {
				list.add(rs.getString(1));
			}
			return list;
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("获取list集合第一列数据失败",e);
		}
	}
	/**
	 * 执行select语句，返回被封装为Integer对象的第一行的第一列数据。
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public Integer queryInteger(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			if(rs.next()){
				return rs.getInt(1);
			}
			return null;
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("获取integer对象第一行第一列数据失败", e);
		}
	}
	/**
	 * 执行select语句，返回被封装为List集合第一列数据，集合中的每一个元素为一个Integer对象封装一行的第一列数据。
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public List<Integer> queryIntegerList(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		List<Integer>list=new ArrayList<>();
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			while(rs.next()) {
				list.add(rs.getInt(1));
			}
			return list;
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("获取list集合中的integer对象第一行第一列数据失败", e);
		}
	}
	/**
	 * 执行select语句，返回被封装为Long对象的第一行的第一列数据。
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public Long queryLong(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			if(rs.next()){
				return rs.getLong(1);
			}
			return null;
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("封装Long对象第一行第一列数据失败", e);
		}	
	}
	/**
	 * 执行select语句，返回被封装为List集合第一列数据，集合中的每一个元素为一个Long对象封装一行的第一列数据。
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public List<Long> queryLongList(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		List<Long> list=new ArrayList<>();
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			while(rs.next()) {
				list.add(rs.getLong(1));
			}
			return list;
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("获取list封装long集合第一行第一列失败", e);
		}
	}
	/**
	 * 执行select语句，返回被封装为Float对象的第一行的第一列数据。
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public Float queryFloat(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			if(rs.next()){
				return rs.getFloat(1);
			}
			return null;
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("封装Float第一行第一列失败",e);
		}
	}
	/**
	 * 执行select语句，返回被封装为List集合第一列数据，集合中的每一个元素为一个Float对象封装一行的第一列数据。
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public List<Float> queryFloatList(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		List<Float> list=new ArrayList<>();
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			while(rs.next()) {
				list.add(rs.getFloat(1));
			}
			return list;
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("获取list封装float集合第一行第一列失败", e);
		}
		
	}
	/**
	 * 执行select语句，返回被封装为Double对象的第一行的第一列数据。
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public Double queryDouble(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			if(rs.next()){
				return rs.getDouble(1);
			}
			return null;
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("封装double第一行第一列失败", e);
		}
	}
	/**
	 * 执行select语句，返回被封装为List集合第一列数据，集合中的每一个元素为一个Double对象封装一行的第一列数据。
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public List<Double> queryDoubleList(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		List <Double>list=new ArrayList<>();
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			while(rs.next()) {
				list.add(rs.getDouble(1));
			}
			return list;
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("获取list封装double集合第一行第一列失败", e);
		}
	}
	/**
	 * 执行select语句，返回被封装为Java.util.Date对象的第一行的第一列数据。
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public Date queryDate(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			for(int i=0;i<args.length;i++) {
				if(args[i] instanceof java.util.Date) {
					java.util.Date d=(Date)args[i];//类型转换
					/*
					 * java.sql.Date 年 月 日
					 * java.sql.Time 时 分 秒
					 * java.sql.Timestamp 年 月 日 时 分 秒 毫秒--通常情况下使用该方法
					 */ 
					pt.setTimestamp(i+1, new java.sql.Timestamp(d.getTime()));
				}else {
					pt.setObject(i+1, args[i]);
				}
			}
			if(rs.next()){
				return rs.getTimestamp(1);
			}
			return null;
			//判断时间格式
		} catch (SQLException e) {
			e.printStackTrace();
			throw new DaoException("封装date第一行第一列失败", e);
		}
	}
	/**
	 * 执行select语句，返回被封装为List集合第一列数据，集合中的每一个元素为一个java.util.Date对象封装一行的第一列数据。
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public List<Date> queryDateList(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		List<Date>list=new ArrayList<>();
		try {
			for(int i=0;i<args.length;i++) {
				if(args[i]instanceof java.util.Date) {
				  java.util.Date d= (Date)args[i];
				  pt.setTimestamp(i+1, new java.sql.Timestamp(d.getTime()));
				}else {
					pt.setObject(i+1, args[i]);
				}
			}
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			while(rs.next()) {
				list.add(rs.getTimestamp(1));
			}
			return list;
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("获取list封装Date集合第一行第一列失败", e);
		}
	}
	/**
	 * 执行select语句，返回被封装为Map<String,Object>对象的第一行查询结果，
	 * 其中Map<String,Object>对象的键为小写的列标名称，值为对应的列值。
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */	
	@Override
	public Map<String, Object> queryMap(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		Map<String, Object> map=new HashMap<>();
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			if(rs.next()) {
				int count=rs.getMetaData().getColumnCount();
				for(int i=1;i<=count;i++) {
					String key=rs.getMetaData().getColumnLabel(i);
					Object value=rs.getObject(i);
					map.put(key, value);
				}
			}
			return map;
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("封装Map对象第一行失败", e);
		}
	}
	/**
	 * 执行select语句，返回被封装为List集合的查询结果，集合中的每一个元素为一个Map<String,Object>对象封装一行数据，
	 * 其中Map<String,Object>对象的键为小写的列标名称，值为对应的列值。
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */	
	@Override
	public List<Map<String, Object>> queryMapList(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		List<Map<String, Object>> list=new ArrayList<>();
		Map<String, Object> map=new HashMap<>();
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));//获取结果集
			while(rs.next()) {//结果集遍历
				int count=rs.getMetaData().getColumnCount();//获取一行内列的个数
				for(int i=1;i<=count;i++) {
					String key=rs.getMetaData().getColumnLabel(i);//获取列名称
					Object value=rs.getObject(i);//获取列对应的值
					map.put(key, value);//将该列的key和value对应的键值对添加到map中
				}
				list.add(map);//将map添加到list中
			}
			return list;
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("封装List<Map<String,Object>>集合失败", e);
		}
	}
	/**
	 * 执行select语句，返回被封装为Object[]对象的第一行查询结果。
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */	
	@Override
	public Object[] queryArray(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			int count=rs.getMetaData().getColumnCount();
			Object[] obj=new Object[count];
			if(rs.next()) {
				for(int i=0;i<count;i++) {
					obj[i]=rs.getObject(i+1);	
				}
			}
			return obj;
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("封装Object[]对象第一行是失败", e);
		}
	}
	/**
	 * 执行select语句，返回被封装为List集合的查询结果，集合中的每一个元素为一个Object[]对象封装一行数据。
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */	
	@Override
	public List<Object[]> queryArrayList(String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		List<Object[]> list=new ArrayList<Object[]>();
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			while(rs.next()) {
				int count=rs.getMetaData().getColumnCount();//获取列数
				Object[] obj=new Object[count];
				for(int i=0;i<obj.length;i++) {
					obj[i]=rs.getObject(i+1);
				}
				list.add(obj);//把获取到的每一行数据添加到list中去
			}
			return list;
		}catch(Exception e) {
			throw new DaoException("封装list集合Object对象失败", e);
		}
	}
	/**
	 * 执行select语句，返回被封装为Java对象的第一行的第一列查询结果，结果类型由参数valueClass指定。
	 * @param valueClass
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public <T> T queryUniqueValue(Class<T> valueClass, String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			if(rs.next()){
				ValueRowMapper<T> mapper=new ValueRowMapper<>(valueClass);
				return (T) mapper.toObject(rs);
			}
			return null;
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("封装第一行第一列类型由varlueClass指定失败", e);
		}
	}
	/**
	 * 执行select语句，返回被封装为List集合的第一列查询结果，集合元素的类型由参数varlueClass指定。
	 * @param valueClass
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public <T> List<T> queryValueList(Class<T> valueClass, String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		List<T> list=new ArrayList<>();
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			ValueRowMapper<T> mapper=new ValueRowMapper<>(valueClass);
			while(rs.next()) {
				list.add(mapper.toObject(rs));
			}
			return list;
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("封装List集合第一列失败", e);
		}
		
	}
	/**
	 * 执行select语句，返回被封装为JavaBean对象第一条的查询记录，JavaBean对象类型由参数beanClass指定。
	 * 注：数据记录按列标名称与JavaBean属性名称匹配的原则封装为JavaBean对象。
	 * @param beanClass
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public <T> T queryBean(Class<T> beanClass, String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			if(rs.next()){
				beanRowMapper<T> mapper=new beanRowMapper<T>(beanClass,rs);
				return (T) mapper.toObject(rs);
			}
			return null;	
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("封装JavaBean对象第一条失败", e);
		}
	}
	/**
	 * 执行select语句，返回被封装为List集合的查询结果，集合中的元素为封装了一条数据记录的JavaBean对象，JavaBean对象类型由参数beanClass指定。
	 * 注：数据记录按列标名称与JavaBean属性名称匹配的原则封装为JavaBean对象。
	 * @param beanClass
	 * @param sql
	 * @param args
	 * @return
	 * @throws DaoException
	 */
	@Override
	public <T> List<T> queryBeanList(Class<T> beanClass, String sql, Object... args) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		List<T> list=new ArrayList<T>();
		try {
			rs=getResultSet(setArgs(createPreparedStatement(sql),args));
			beanRowMapper <T>mapper=new beanRowMapper<T>(beanClass,rs);
			while(rs.next()) {
				list.add(mapper.toObject(rs));
			}
			return list;
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("list集合封装JavaBean失败", e);
		}	
	}
	/**
	 * 创建PreSQL对象
	 * @param sql
	 * @return
	 * @throws DaoException
	 */
	@Override
	public PreSQL preSql(String sql) throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启");
		}
		logger.debug("Sql语句："+sql);
		try {
			pt=createPreparedStatement(sql);
			return new PreSql(pt);
		}catch(Exception e) {
			e.printStackTrace();
			throw new DaoException("创建PreSQL失败", e);
		}
	}
	//创建内部类
	public class PreSql implements PreSQL{
		//定义private 属性
		private PreparedStatement pt;
		public PreSql(PreparedStatement pt) {//有参构造器
			this.pt = pt;
		}
		/**
		 * 执行查询sql，返回ResultSet
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		@Override
		public ResultSet query(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			try {
				return getResultSet(setArgs(pt,args));
			} catch (SQLException e) {
				e.printStackTrace();
				throw new DaoException("数据库查询结果集出错", e);
			}
		}
		/**
		 * 执行更新sql，返回影响行数
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		@Override
		public int update(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			try {
				return setArgs(pt, args).executeUpdate();
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("返回影响行失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为List集合的查询结果，集合中的每一个元素为一个Java对象封装一行数据。
		 * 注：如何将一行数据封装为Java对象由RowMapper类型的对象参数决定。
		 * @param mapper
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		@Override
		public <T> List<T> queryList(RowMapper<T> mapper, Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			List<T> list=new ArrayList<>();
			try {
				rs=getResultSet(setArgs(pt,args));
				while(rs.next()) {
					list.add(mapper.toObject(rs));
				}
				return list;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("封装list集合查询结果失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为Java对象的第一行查询结果。
		 * 注：如何将一行数据封装为Java对象由RowMapper类型的对象参数决定。
		 * @param mapper
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		@Override
		public <T> T queryUnique(RowMapper<T> mapper, Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			try {
				rs=getResultSet(setArgs(pt,args));
				if(rs.next()){
					return mapper.toObject(rs);
				}
				return null;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("封装第一行查询结果失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为String对象的第一行的第一列数据。
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		@Override
		public String queryString(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			try {
				rs=getResultSet(setArgs(pt,args));
				if(rs.next()){
					return rs.getNString(1);
				}
				return null;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("封装String对象第一行第一列失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为List集合第一列数据，集合中的每一个元素为一个String对象封装一行的第一列数据。
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		@Override
		public List<String> queryStringList(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			List<String> list=new ArrayList<>();
			try {
				rs=getResultSet(setArgs(pt,args));
				if(rs.next()){
					for(int i=0;i<rs.getMetaData().getColumnCount();i++) {
						list.add(rs.getString(i+1));
					}
				}
				return list;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("封装list集合String对象失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为Integer对象的第一行的第一列数据。
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		@Override
		public Integer queryInteger(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			try {
				rs=getResultSet(setArgs(pt,args));
				if(rs.next()){
					return rs.getInt(1);
				}
				return null;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("封装Integer对象第一行第一列失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为List集合第一列数据，集合中的每一个元素为一个Integer对象封装一行的第一列数据。
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		@Override
		public List<Integer> queryIntegerList(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			List <Integer>list=new ArrayList<>();
			try {
				rs=getResultSet(setArgs(pt,args));
				while(rs.next()) {
					list.add(rs.getInt(1));
				}
				return list;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("封装List集合第一列Integer对象失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为Long对象的第一行的第一列数据。
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		@Override
		public Long queryLong(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			try {
				rs=getResultSet(setArgs(pt,args));
				if(rs.next()){
					return rs.getLong(1);
				}
				return null;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("封装第一行第一列Long对象失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为List集合第一列数据，集合中的每一个元素为一个Long对象封装一行的第一列数据。
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		@Override
		public List<Long> queryLongList(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			List<Long> list=new ArrayList<>();
			try {
				rs=getResultSet(setArgs(pt,args));
				while(rs.next()) {
					list.add(rs.getLong(1));
				}
				return list;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("List集合封装第一列Long对象失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为Float对象的第一行的第一列数据。
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		@Override
		public Float queryFloat(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			try {
				rs=getResultSet(setArgs(pt,args));
				if(rs.next()){
					return rs.getFloat(1);
				}
				return null;
				
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("封装Float对象第一行第一列失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为List集合第一列数据，集合中的每一个元素为一个Float对象封装一行的第一列数据。
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		@Override
		public List<Float> queryFloatList(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			List <Float>list=new ArrayList<>();
			try {
				rs=getResultSet(setArgs(pt,args));
				while(rs.next()) {
					list.add(rs.getFloat(1));
				}
				return list;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("list封装Float第一行第一列失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为Double对象的第一行的第一列数据。
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		public Double queryDouble(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			try {
				rs=getResultSet(setArgs(pt,args));
				if(rs.next()){
					return rs.getDouble(1);
				}
				return null;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("封装double对象第一行第一列失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为List集合第一列数据，集合中的每一个元素为一个Double对象封装一行的第一列数据。
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		public List<Double> queryDoubleList(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			List <Double>list=new ArrayList<>();
			try {
				rs=getResultSet(setArgs(pt,args));
				while(rs.next()) {
					list.add(rs.getDouble(1));
				}
				return list;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("list封装doube第一行第一列失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为Java.util.Date对象的第一行的第一列数据。
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		public Date queryDate(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			try {
				for(int i=0;i<args.length;i++) {
					logger.debug(args[i]);
					if(args[i] instanceof java.util.Date) {
						java.util.Date d=(Date)args[i];//类型转换
						/*
						 * java.sql.Date 年 月 日
						 * java.sql.Time 时 分 秒
						 * java.sql.Timestamp 年 月 日 时 分 秒 毫秒--通常情况下使用该方法
						 */ 
						pt.setTimestamp(i+1, new java.sql.Timestamp(d.getTime()));
					}else {
						pt.setObject(i+1, args[i]);
					}
				}
				rs=getResultSet(setArgs(pt,args));
				while(rs.next()){
					return rs.getTimestamp(1);
				}
				return null;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("封装Java.util.Date对象第一行第一列失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为List集合第一列数据，集合中的每一个元素为一个java.util.Date对象封装一行的第一列数据。
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		public List<Date> queryDateList(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			try {
				List<Date> list = new ArrayList<Date>();
				rs=getResultSet(setArgs(pt,args));
				while (rs.next()) {
					list.add(rs.getTimestamp(1));
				}
				return list;
			} catch (SQLException e) {
				throw new DaoException("list集合封装java.util.Date对象第一行第一列失败", e);
			}
			/*
			List <Date>list=new ArrayList<>();
			try {
				for(int i=0;i<args.length;i++) {
					if(args[i]instanceof java.util.Date) {
						java.util.Date d=(Date)args[i];
						pt.setTimestamp(i+1, new java.sql.Timestamp(d.getTime()));
					}else {
						pt.setObject(i+1, args[i]);
					}
					rs=getResultSet(setArgs(pt,args));
					while(rs.next()) {
						list.add(rs.getTimestamp(1));
					}
				}
				return list;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("list集合封装java.util.Date对象第一行第一列失败", e);
			}
			*/
		}
		/**
		 * 执行select语句，返回被封装为Map<String,Object>对象的第一行查询结果，
		 * 其中Map<String,Object>对象的键为小写的列标名称，值为对应的列值。
		 * @param args
		 * @return
		 * @throws DaoException
		 */	
		public Map<String, Object> queryMap(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			Map<String, Object> map=new HashMap<>();
			try {
				rs=getResultSet(setArgs(pt,args));
				while(rs.next()) {
					for(int i=1;i<=rs.getMetaData().getColumnCount();i++) {
						String key=rs.getMetaData().getColumnLabel(i);
						Object value=rs.getObject(i);
						map.put(key, value);
					}
				}
				return map;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("封装Map<String,Object>对象第一行失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为List集合的查询结果，集合中的每一个元素为一个Map<String,Object>对象封装一行数据，
		 * 其中Map<String,Object>对象的键为小写的列标名称，值为对应的列值。
		 * @param args
		 * @return
		 * @throws DaoException
		 */	
		public List<Map<String, Object>> queryMapList(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			List<Map<String,Object>>list=new ArrayList<>();
			Map<String, Object> map=new HashMap<>();
			try {
				rs=getResultSet(setArgs(pt,args));
				while(rs.next()) {
					for(int i=1;i<=rs.getMetaData().getColumnCount();i++) {
						String key=rs.getMetaData().getColumnLabel(i);
						Object value=rs.getObject(i);
						map.put(key, value);
					}
					list.add(map);
				}
				return list;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("list集合封装Map<String,Objeect>对象第一行失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为Object[]对象的第一行查询结果。
		 * @param args
		 * @return
		 * @throws DaoException
		 */	
		public Object[] queryArray(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			try {
				rs=getResultSet(setArgs(pt,args));
				int num=rs.getMetaData().getColumnCount();
				Object []obj = new Object[num];
				if(rs.next()) {
					for(int i=0;i<num;i++) {
						obj[i]=rs.getObject(i++);
					}
				}
				return obj;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("封装Object[]对象第一行失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为List集合的查询结果，集合中的每一个元素为一个Object[]对象封装一行数据。
		 * @param args
		 * @return
		 * @throws DaoException
		 */	
		public List<Object[]> queryArrayList(Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			List <Object[]>list=new ArrayList<>();
			try {
				rs=getResultSet(setArgs(pt,args));
				while(rs.next()) {
					int num=rs.getMetaData().getColumnCount();
					Object []obj = new Object[num];
					for(int i=0;i<num;i++) {
						obj[i]=rs.getObject(i+1);
					}
					list.add(obj);
				}
				return list;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("list封装object[]对象失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为Java对象的第一行的第一列查询结果，结果类型由参数varlueClass指定。
		 * @param valueClass
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		public <T> T queryUniqueValue(Class<T> valueClass, Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			try {
				ValueRowMapper<T> mapper=new ValueRowMapper<>(valueClass);
				rs=getResultSet(setArgs(pt,args));
				if(rs.next()){
					return mapper.toObject(rs);
				}
				return null;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("封装Java对象第一行第一列失败参数", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为List集合的第一列查询结果，集合元素的类型由参数varlueClass指定。
		 * @param valueClass
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		public <T> List<T> queryValueList(Class<T> valueClass, Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			List <T>list=new ArrayList<>();
			try {
				ValueRowMapper <T>mapper=new ValueRowMapper<>(valueClass);
				rs=getResultSet(setArgs(pt,args));
				while(rs.next()) {
					list.add(mapper.toObject(rs));
				}
				return list;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("list封装第一列失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为JavaBean对象第一条的查询记录，JavaBean对象类型由参数beanClass指定。
		 * 注：数据记录按列标名称与JavaBean属性名称匹配的原则封装为JavaBean对象。
		 * @param beanClass
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		public <T> T queryBean(Class<T> beanClass, Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			try {
				rs=getResultSet(setArgs(pt,args));
				beanRowMapper<T> mapper=new beanRowMapper<>(beanClass,rs);
				if(rs.next()){
					return mapper.toObject(rs);
				}
				return null;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("封装javaBean对象失败", e);
			}
		}
		/**
		 * 执行select语句，返回被封装为List集合的查询结果，集合中的元素为封装了一条数据记录的JavaBean对象，JavaBean对象类型由参数beanClass指定。
		 * 注：数据记录按列标名称与JavaBean属性名称匹配的原则封装为JavaBean对象。
		 * @param beanClass
		 * @param args
		 * @return
		 * @throws DaoException
		 */
		public <T> List<T> queryBeanList(Class<T> beanClass, Object... args) throws DaoException {
			if(!flag){
				throw new DaoException("事务尚未开启");
			}
			for (int i = 0; i < args.length; i++) {
				logger.debug(args[i]);
			}
			List <T>list=new ArrayList<>();
			try {
				rs=getResultSet(setArgs(pt,args));
				beanRowMapper<T> mapper=new beanRowMapper<>(beanClass,rs);
				while(rs.next()) {
					list.add(mapper.toObject(rs));
				}
				return list;
			}catch(Exception e) {
				e.printStackTrace();
				throw new DaoException("list封装JavaBean对象失败", e);
			}
		}
	}
	/**
	 * 开启当前事务
	 */
	public void beginTx() throws DaoException {
		if(flag){
			throw new DaoException("事务不能重新开启");
		}else{
			flag=true;
			logger.debug("事务开启!");
		}
	}
	/**
	 * 提交当前事务
	 */
	public void commitTx() throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启,无法提交");
		}else{
			try {
				con.commit();
				logger.debug("事务提交!");
			} catch (SQLException e) {
				e.printStackTrace();
			}	
		}
	}
	/**
	 * 回滚当前事务
	 */
	public void rollbackTx() throws DaoException {
		if(!flag){
			throw new DaoException("事务尚未开启，无法回滚！");
		}else {
			try {
				con.rollback();
				logger.debug("事务回滚!");
			} catch (SQLException e) {
				e.printStackTrace();
			}
		}
	}
}